package tech.treec.smartlight.service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import androidx.core.app.NotificationCompat;
import androidx.preference.PreferenceManager;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.young.mylib.OKHttpClient;
import com.young.mylib.db.DatabaseUtils;
import com.young.mylib.db.dao.DeviceDao;
import com.young.mylib.db.entity.DeviceDataEntity;
import com.young.mylib.db.entity.DeviceEntity;
import com.young.mylib.db.entity.DeviceRealtimeDataEntity;
import com.young.mylib.db.entity.LinkageEntity;
import com.young.mylib.db.entity.LinkageLog;
import com.young.mylib.utils.ConverterUtils;
import com.young.mylib.utils.JsonUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import tech.treec.smartlight.LoggerUtil;
import tech.treec.smartlight.R;

import com.young.mylib.HttpCallback;
import com.young.mylib.utils.Log4AUtils;
import com.young.mylib.utils.TimeUtils;

import static tech.treec.smartlight.Constants.ACTION_LINKAGE_CONFIG_RECEIVE;
import static tech.treec.smartlight.Constants.ACTION_MQTT_CONNECTED;
import static tech.treec.smartlight.Constants.ACTION_MQTT_PUB_MSG;
import static tech.treec.smartlight.Constants.ACTION_MQTT_SUB_MSG;
import static tech.treec.smartlight.Constants.ACTION_MQTT_SUB_MSG_RECEIVE;
import static tech.treec.smartlight.Constants.ACTION_REQUEST_LINKAGE_CONFIG;
import static tech.treec.smartlight.Constants.DEVICE_TYPE_AIR;
import static tech.treec.smartlight.Constants.DEVICE_TYPE_BODY;
import static tech.treec.smartlight.Constants.DEVICE_TYPE_LIGHT;

public class DeviceService extends Service implements HttpCallback {
    private static final String TAG = "DeviceService";
    private Timer serviceTimer = null;
    private MqttMsgReceiver msgReceiver;
    private Map<String, Integer> reconfirm = new HashMap<>();//二次确认的记数

    public DeviceService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "mqtt 服务建立");
        // reset status variable to initial state

        serviceTimer = new Timer();
        serviceTimer.schedule(timerTask, 1000, 60 * 1000);
      //  requestLinkage();

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_MQTT_SUB_MSG_RECEIVE);
        intentFilter.addAction(ACTION_MQTT_CONNECTED);
        intentFilter.addAction(ACTION_REQUEST_LINKAGE_CONFIG);
        msgReceiver = new MqttMsgReceiver();
        registerReceiver(msgReceiver, intentFilter);

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onHttpResponse(String url, String msg) {

    }

    @Override
    public void onFail(String url, String msg) {

    }

    @Override
    public void onStart(final Intent intent, final int startId) {
        Log.i(TAG, "onStart");
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, final int startId) {
        Log.i(TAG, "onStartCommand");
        startForeground(1, getNotfication());
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (msgReceiver != null) {
            unregisterReceiver(msgReceiver);
        }

    }

    private Notification getNotfication() {
        String channelId = "smart_light_channel";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId, "SMART LIGHT CHANNEL", NotificationManager.IMPORTANCE_DEFAULT);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
                .setContentTitle("Service Running")
                .setContentText("MyService is running in the foreground")
                .setSmallIcon(R.drawable.app);
        return builder.build();

    }

    private int timeCount = 0;
    TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {

//            timeCount++;
//            boolean isSendCmd = false;
//            if (timeCount > 5) {
//                isSendCmd = true;
//                timeCount = 0;
//            }
//            //  sendReconfirmCmd("466_22400401");
//            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
//            boolean _isEnabled = prefs.getBoolean("isEnabled", true);
//            Log4AUtils.info("开始检查是否有人：" + _isEnabled);
//            if (!_isEnabled) return;
//            List<LinkageEntity> linkages = DatabaseUtils.getHelper().queryAll(LinkageEntity.class);//所有的场景配置
//            Log.i(TAG, "检查是否有人：" + linkages.size());
//            for (LinkageEntity linkageEntity : linkages) {
//                boolean isEnabled = linkageEntity.isEnabled;
//                JSONArray devices = linkageEntity.devices;
//                //   Log.i(TAG, "检查联动设备 " + entity.name + ":" + isEnabled + ":" + devices.size());
//                /**
//                 * 1、判断是否启动，是否有设备
//                 * 2、判断是否有人体感应设备
//                 * 3、判断其它设备状态是否有为1的
//                 */
//                boolean hasBody = false;//是否有人体感应设备
//                boolean hasAction = false;//有否有开着的其它设备
//                List<String> airDevices = new ArrayList<>();
//                List<String> lightDevices = new ArrayList<>();
//                List<String> bodyDevices = new ArrayList<>();
//
//                if (isEnabled && devices.size() > 0) {
//                    for (Object dev : devices) {
//                        DeviceEntity device = JsonUtils.toBean(dev.toString(), DeviceEntity.class);
//                        String deviceId = device.deviceId;
//                        DeviceDataEntity lightDeviceRealtimeData = DeviceDao.findRealDataByKey("deviceId", deviceId);
//                        if (lightDeviceRealtimeData.lightStatus == 1) {
//                            hasAction = true;
//                        }
//                        if (getDeviceType(deviceId).equals(DEVICE_TYPE_BODY)) {
//                            hasBody = true;
////                            if (isSendCmd) {
////                                sendReconfirmCmd(deviceId);//todo 危险
////                                Log.i(TAG, "@@@@@@@@@@@@@@@@ ######### 发送指令");
////                            }
//                            bodyDevices.add(deviceId);
//                        } else if (getDeviceType(deviceId).equals(DEVICE_TYPE_LIGHT)) {
//                            lightDevices.add(deviceId);
//                        } else {
//                            airDevices.add(deviceId);
//                        }
//                    }
//                }
//
//                if (hasAction && hasBody) {//有开关的灯、有人体感应设备
//                    LinkageLog linkageLog = new LinkageLog();
//                    linkageLog.name = linkageEntity.name;
//                    linkageLog.delayTime = linkageEntity.delayTime;
//
//                    //Log.i(TAG, "###### " + linkageEntity.name + " 检查是否无人 ###########");
//
//                    int delayTime = linkageEntity.delayTime;
//                    boolean isNoBody = true;
//                    String time = TimeUtils.getCurrentTimeAnd8();
//                    long lastTs = TimeUtils.getCurrTsBeforeMinute(-delayTime);
//                    String lastTime = TimeUtils.getTimeAnd8(lastTs);
//
//                    String logs = "";
//                    for (String id : bodyDevices) {
//                        List<DeviceDataEntity> list = DeviceDao.findDataByRangeAndKey(lastTs, "deviceId", id);
//
//                        if (list == null || list.size() == 0) {
//                            logs += linkageEntity.name + " ******* 设备数据为空 ************";
//                            isNoBody = false;
//                        }
//
//                        if (list != null) {
//                            for (DeviceDataEntity deviceDataEntity : list) {
//                                logs += "\r\n" + deviceDataEntity.deviceName + "设备状态数据为：" + deviceDataEntity.lightStatus + "：" + deviceDataEntity.time;
//                                if (deviceDataEntity.lightStatus == 1) {
//                                    isNoBody = false;
//                                }
//                            }
//                        }
//                    }
//                    Log4AUtils.info(logs);
//
//                    String str = isNoBody ? "无人" : "有人";
//                    String log = "$$$$$$$$ " + linkageEntity.name + " $$$$$$$$$$$$$ " + linkageEntity.delayTime + "分钟内" + "判断为######### " + str + " ########，时间范围：" + time + ":" + lastTime;
//                    Log.i(TAG, log);
//                    // Log4AUtils.info(log);
//                    boolean isCloseAir = false, isCloseLight = false;
//                    if (!isNoBody) {
//                        reconfirm.put(linkageEntity.treeId, 0);
//                    }
//
//                    /**
//                     * 如果没有二次确认的值，是第一次
//                     * 记为2，下次再确认
//                     */
//
//
//                    if (isNoBody && reconfirm.get(linkageEntity.treeId) == 0) {//第一次，确认
//                        reconfirm.put(linkageEntity.treeId, 1);
//                        isNoBody = false;//不执行
//                        Log4AUtils.info(linkageEntity.name + " 第一次无人状态，不执行！！");
//                        sendReconfirmCmd(bodyDevices);//二次确认
//
//                    }
//
//                    if (isNoBody) {
//                        Log4AUtils.info(linkageEntity.name + " 第二次无人状态，执行！！！");
//                        reconfirm.put(linkageEntity.treeId, 0);
//                        for (String did : airDevices) {
//                            DeviceRealtimeDataEntity deviceDataEntity = DeviceDao.findRealDataByKey("deviceId", did);
//                            if (deviceDataEntity != null && deviceDataEntity.lightStatus == 1) {
//                                Log.i(TAG, deviceDataEntity.deviceName + ":" + deviceDataEntity.lightStatus);
//                                String topic = did + "/ctrlReport";
//                                JSONObject payload = new JSONObject();
//                                payload.put("switch", 0);
//
//                                Intent subIntent = new Intent();
//                                subIntent.putExtra("topic", topic);
//                                subIntent.putExtra("payload", payload.toJSONString());
//                                subIntent.setAction(ACTION_MQTT_PUB_MSG);
//                                sendBroadcast(subIntent);
//                                Log4AUtils.info("@@@@@@@@@ 执行关空调操作：" + linkageEntity.name + ":" + deviceDataEntity.deviceName);
//                                isCloseAir = true;
//                            } else {
//                                Log.i(TAG, "空调数据为空或为0 " + did);
//                            }
//                        }
//                        for (String did : lightDevices) {
//                            DeviceRealtimeDataEntity deviceDataEntity = DeviceDao.findRealDataByKey("deviceId", did);
//
//                            if (deviceDataEntity != null && deviceDataEntity.lightStatus == 1) {
//                                //  Log.i(TAG, deviceDataEntity.deviceName + ":" + deviceDataEntity.lightStatus);
//                                String topic = did + "/ctrlReport";
//                                JSONObject payload = new JSONObject();
//                                payload.put("status", 0);
//
//                                Intent subIntent = new Intent();
//                                subIntent.putExtra("topic", topic);
//                                subIntent.putExtra("payload", payload.toJSONString());
//                                subIntent.setAction(ACTION_MQTT_PUB_MSG);
//                                sendBroadcast(subIntent);
//                                isCloseLight = true;
//                                Log4AUtils.info("@@@@@@@@@@@@@@@@ 执行关灯操作：" + linkageEntity.name + ":" + deviceDataEntity.deviceName + ":" + deviceDataEntity.deviceId);
//                            } else {
//                                Log.i(TAG, "照明数据为空或为0 " + did);
//                            }
//                        }
//                        if (isCloseAir || isCloseLight) {
//                            String msg = "无人状态，";
//                            if (isCloseAir) {
//                                msg += "关闭空调；";
//                            } else {
//                                msg += "空调已关闭；";
//                            }
//                            if (isCloseLight) {
//                                msg += "关闭照明。";
//                            } else {
//                                msg += "照明已关闭。";
//                            }
//                            linkageLog.msg = msg;
//                            linkageLog.ts = TimeUtils.getCurrTs();
//                            linkageLog.time = time;
//
//                            DeviceDao.saveLinkageLog(linkageLog);
//                        }
//                    }
//                } else {
//                    //  Log.i(TAG, linkageEntity.name + " 无开着的灯?" + isEnabled + "->device: " + devices.size());
//                }
//            }
        }
    };

    /**
     * 下发一条配置的指令，进行二次确认
     *
     * @param bodyDevices
     */

    private void sendReconfirmCmd(List<String> bodyDevices) {
        for (String deviceId : bodyDevices) {
            sendReconfirmCmd(deviceId);
        }
    }

    private void sendReconfirmCmd(String deviceId) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        String _confirmSec = prefs.getString("confirmSec", "120"); // 获取默认值作为备选方案。
        int confirmSec = ConverterUtils.str2int(_confirmSec, 120);
        String _confirmSec_out = prefs.getString("confirmSec_out", "20");
        int confirmSec_out = ConverterUtils.str2int(_confirmSec_out, 20);
        String panelId = prefs.getString("panelId", "588");
        String topic = "/light/DARMAO000" + panelId + "0000/ctrl/report";
        //{"deviceId":"364_39370401","confirmSec":20,"confirmSec_out":1000}

        JSONObject json = new JSONObject();
        json.put("deviceId", deviceId);
        json.put("confirmSec", confirmSec);
        json.put("confirmSec_out", confirmSec_out);
        Log.i(TAG, "发送确认指令：" + json.toJSONString());
        Log4AUtils.info("发送确认指令：" + json.toJSONString());
        Log4AUtils.info(topic + " 发送确认指令：" + json.toJSONString());
        Intent subIntent = new Intent();
        subIntent.putExtra("topic", topic);
        subIntent.putExtra("payload", json.toJSONString());
        subIntent.setAction(ACTION_MQTT_PUB_MSG);
        sendBroadcast(subIntent);

    }



    /**
     * 请求配置
     */
    private void requestConfig() {
        Log.i(TAG, "请求配置数据");
        JSONObject json = new JSONObject();

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        String brokerHostName = prefs.getString("serverUrl", "10.13.60.248"); // 获取默认值作为备选方案。
        String port = prefs.getString("serverPort", "28900");
        String panelId = prefs.getString("panelId", "588");
        json.put("label", panelId);
        String url = "http://" + brokerHostName + ":" + port + "/api/rule/config/find";
        Log.i(TAG, "获取配置:" + url);
        OKHttpClient.getInstance().postJson(url, json.toJSONString(), new HttpCallback() {
            @Override
            public void onHttpResponse(String url, String msg) {

                JSONObject json = JsonUtils.toJsonObject(msg);
                if (json != null) {
                    boolean isEnabled = json.getBoolean("isEnabled");//是否启用场景联动；
                    SharedPreferences.Editor editor = prefs.edit();
                    editor.putBoolean("isEnabled", isEnabled);
                    editor.commit();
                }

            }

            @Override
            public void onFail(String url, String msg) {

            }
        });
    }

    private class MqttMsgReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            if (action.equals(ACTION_REQUEST_LINKAGE_CONFIG)) {
             //   requestLinkage();
                return;
            }

            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
            String panelId = prefs.getString("panelId", "588"); // 获取默认值作为备选方案。
            String suTopic = "/light/DARMAO000" + panelId + "0000/data/report/app";
            long ts = TimeUtils.getCurrTs();
            String time = TimeUtils.getCurrentTimeAnd8();
            String topic = intent.getStringExtra("topic");
            String payload = intent.getStringExtra("payload");
            String cmdTopic = panelId + "/cmd";

            if (topic.equals(cmdTopic) && payload.equals("linkage")) {
              //  requestLinkage();
            }
            if (topic.equals(cmdTopic) && payload.equals("config")) {
                requestConfig();
            }
            /**
             * 中控屏数据到达
             */
            if (topic.equals(suTopic)) {
                try {
                    JSONObject json = JsonUtils.toJsonObject(payload);
                    if (json == null) return;
                    for (Map.Entry<String, Object> entry : json.entrySet()) {
                        String deviceId = entry.getKey();
                        Object obj = entry.getValue();
                        //  Log.i(TAG, "设备上报数据：" + json.toJSONString());
                        DeviceEntity device = DeviceDao.findDevice(deviceId);
                        if (device != null) {
                            DeviceDataEntity deviceDataEntity = new DeviceDataEntity();
                            deviceDataEntity.deviceId = deviceId;
                            deviceDataEntity.deviceName = device.deviceName;
                            deviceDataEntity.deviceType = getDeviceType(deviceId);
                            deviceDataEntity.lightStatus = ConverterUtils.str2int(obj.toString(), 0);
                            deviceDataEntity.time = time;
                            deviceDataEntity.ts = ts;
                            String log = "保存设备上报数据：" + deviceDataEntity.deviceName + ":" + deviceDataEntity.lightStatus + ":" + deviceDataEntity.time;
                            if (deviceId.equals("588_6d2c0401")) {//测试的会议室
                                log += "#######################################";
                                Log.i(TAG, log);
                            }

                            DeviceDao.saveDeviceData(deviceDataEntity);
                            DeviceDao.updateDeviceRealtimeData(deviceDataEntity);
                        }
                    }

                } catch (Exception e) {
                    Log.e(TAG, "MsgReceiver error: " + e.getMessage());
                }
            }
            /**
             * 网关解析后的数据
             */
//            if (topic.contains("/databack") && !topic.contains("/light/DARMAO000")) {
//
//                String deviceId = topic.replace("/databack", "");
//                if (deviceId.equals(null)) return;
//                saveRealtimeData(deviceId, payload);
//            }
        }
    }


    public static String getDeviceType(String deviceId) {
        int num = indexOfStr(deviceId, '_');
        switch (num) {
            case 0:
                return DEVICE_TYPE_AIR;
            case 1:
                return DEVICE_TYPE_BODY;
            case 2:
                return DEVICE_TYPE_LIGHT;
            default:
                return "";
        }
    }

    private static int indexOfStr(String str, char targetChar) {
        int count = 0;

        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == targetChar) {
                count++;
            }
        }
        return count;
    }

}